#ifndef HASH_H
#define HASH_H

#include <stdint.h>
#include <cassert>

namespace {

typedef uint32_t hash_t;

template <typename T>
hash_t hash(T val, hash_t prior);

template <>
hash_t hash<int32_t>(int32_t val, hash_t prior) {
	hash_t hval = static_cast<hash_t>(val);

	hval ^= (~hval << 21) | (hval >> 11);
	hval += 247823117;
	hval ^= (~prior << (prior & 13)) | (prior >> (32 - (prior & 13)));

	hval += hval << 13;
	hval ^= hval >> 7;
	hval += hval << 3;
	hval ^= hval >> 17;
	hval += hval << 5;

	return hval;
}

template <>
hash_t hash<bool>(bool val, hash_t prior) {
	return prior + ((hash_t) val ^ 0x3A9026C3);
}

}

#endif
